<?php
$loader->requireOnce('ordo/Ticket.class.php');
$loader->requireOnce('includes/InPayment/AbsInPayment.class.php');
$loader->requireOnce('includes/InPayment/ExtInPaymentData.class.php');
$loader->requireOnce('includes/InPayment/MedicinePayment.class.php');
$loader->requireOnce('includes/InPayment/MaterialPayment.class.php');
$loader->requireOnce('includes/InPayment/ServicePayment.class.php');
$loader->requireOnce('includes/InPayment/BedPayment.class.php');
$loader->requireOnce('includes/InPayment/TestPayment.class.php');
$loader->requireOnce('includes/EnumerationConstant.class.php');

class InPatientPayment {
	protected  $_db;

	public function __construct(){
        $this->_db          =  $GLOBALS['frame']['adodb']['db'];
    }

    /**
     * Calculate total payments of an examination of an inpatient
     *
     * @param int $patientId Patient Id
     * @param bool $updatePayment Indicate that whether in_payment table is updated or not
     * @return ExtPaymenData Object containing result
     */
    public function calculatePatientPayment($patientId, $updatePayment=false){
        // Step 1: Get all ticket of patient
        $statusOpen =   Ticket::OPEN_STATUS;
        $sql    =   "SELECT ticket_id FROM ticket
                    WHERE patient_id=$patientId AND status='$statusOpen'";
        $res    =   $this->_db->execute($sql);

        // Step 2: Calculate total payments of all opening tickets of patient
        $paymentData    =   new InPaymentData();
        $objInPayment   =   new AbsInPayment($patientId);
        $objMedicine    =   new MedicinePayment($objInPayment);
        $objMaterial    =   new MaterialPayment($objMedicine);
        $objService     =   new ServicePayment($objMaterial);
        $objTest     =      new TestPayment($objService);
        $objBed         =   new BedPayment($objTest);
        while ($res && !$res->EOF){
        	$ticketId  =   $res->fields['ticket_id'];
        	$data      =   $objBed->calculateTicketPayment($ticketId);
	        $paymentData->addDataFromObject($data);
	        $res->moveNext();
        }

        // Step 3: Get advance payment that patient has paid to hospital
        $objEm =   & Celini::enumManagerInstance();
        $statusOpen    =  $objEm->lookupKey(EnumerationConstant::IN_PAY_STATUS,
                    EnumerationConstant::IN_PAY_STATUS_OPEN);
        $sql    =   "SELECT real_payment FROM in_payment
                    WHERE patient_id='$patientId' AND enum_status='$statusOpen'";
        $res    =   $this->_db->execute($sql);
        $advancePayment =   0;
        if($res && !$res->OEF) {
            $advancePayment    =    (is_null($res->fields['real_payment']))?0:$res->fields['real_payment'];
        }
        $extPaymentData =   new ExtInPaymentData();
        $extPaymentData->copyFromObject($paymentData);
        $extPaymentData->setAdvancePayment($advancePayment);
        $extPaymentData->setPatientId($patientId);

        // Step 4: Update in_payment table if needed
        if($updatePayment) {
        	$this->updatePaymentData($extPaymentData);
        }

        return $extPaymentData;
    }

    private function updatePaymentData($paymentData) {
    	$orgPrice  =   $paymentData->getOriginalPrice();
    	$patPrice  =   $paymentData->getPatientPrice();
    	$insPrice  =   $paymentData->getInsurancePrice();
    	$patientId =   $paymentData->getPatientId();
    	$objEm =   & Celini::enumManagerInstance();
        $statusOpen    =  $objEm->lookupKey(EnumerationConstant::IN_PAY_STATUS,
                    EnumerationConstant::IN_PAY_STATUS_OPEN);
        $sql    =   "UPDATE in_payment
                    SET original_price='$orgPrice', insurance_price='$insPrice', patient_price='$patPrice'
                    WHERE patient_id=$patientId AND enum_status=$statusOpen";
        $res    =   $this->_db->execute($sql);
        if($res===false) {
            throw new InPaymentException("Errors on query: '$sql'");
        }

        return true;
    }
}
?>